﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AsycServer
{
    /// <summary>
    /// 收到数据
    /// </summary>
    partial class Program
    {
        public void OnMessage(Client c, MessageBuffer msg)
        {
            int cproto = msg.ReadInt();
            switch (cproto)
            {
                case cProto.CONNECT:
                    break;
                case cProto.READY:
                    if (!userList.ContainsKey(c))
                    {
                        int id = msg.ReadInt();
                        userList.Add(c, id);
                    }

                    //所有的玩家都准备好了，可以开始同步
                    if (userList.Count >= clientList.Count)
                    {
                        //帧序列从1开始
                        frameCount = 1;
                        
                        //初始化关键帧
                        keyDic = new Dictionary<int, Dictionary<int, List<string>>>();
                        string playStr = "";
                        List<string> playList = new List<string>();
                        foreach (var play in userList)
                        {
                            CharData charData = new CharData(play.Value, play.Value + "_" + play.Value);
                            playList.Add(charData.ToString());
                        }

                        playStr = string.Join(";", playList.ToArray());
                        MessageBuffer buff = new MessageBuffer();
                        buff.WriteInt(cProto.START);
                        buff.WriteString(playStr);

                        //对所有用户发送开始
                        for (int i = 0; i < clientList.Count; ++i)
                        {
                            clientList[i].Send(buff);
                        }
                    }

                    break;
                case cProto.SYNC_POS:
                    //转发给出提交者外的所有的客户端的位置
                    //比如A移动了，A发送数据过来，广播给房间内的B和C,A的位置操作信息
                    for (int i = 0; i < clientList.Count; ++i)
                    {
                        if (c == clientList[i])
                        {
                            continue;
                        }

                        clientList[i].Send(msg);
                    }

                    break;
                case cProto.SYNC_KEY:
                    // 客户端当前帧号
                    int clientCurFrameCount = msg.ReadInt();
                    
                    // 客户端发送的关键数据
                    string keyStr = msg.ReadString();
                    
                    //缓存当前帧好，当前客户端，发送过来的数据
                    if (keyDic.ContainsKey(clientCurFrameCount))
                    {
                        if (keyDic[clientCurFrameCount].ContainsKey(userList[c]))
                        {
                            keyDic[clientCurFrameCount][userList[c]].Add(keyStr);
                        }
                        else
                        {
                            keyDic[clientCurFrameCount][userList[c]] = new List<string>();
                            keyDic[clientCurFrameCount][userList[c]].Add(keyStr);
                        }
                    }
                    else
                    {
                        //确保帧号对应的字典存在
                        keyDic[clientCurFrameCount] = new Dictionary<int, List<string>>();
                        //确保用户对应的列表存在
                        keyDic[clientCurFrameCount][userList[c]] = new List<string>();
                        //添加数据到列表
                        keyDic[clientCurFrameCount][userList[c]].Add(keyStr);
                    }

                    //关键帧广播
                    if (clientCurFrameCount == frameCount)
                    {
                        //判断是否已经收到所有的客户端此帧率的所有数据
                        if (keyDic[clientCurFrameCount].Count == clientList.Count)
                        {
                            List<string> keyDataList = new List<string>();
                            
                            //合并所有用户的数据
                            foreach (var dataList in keyDic[clientCurFrameCount].Values)
                            {
                                keyDataList.AddRange(dataList);
                            }

                            //用分号连接
                            string keyData = string.Join(";", keyDataList.ToArray());
                            MessageBuffer buff = new MessageBuffer();
                            buff.WriteInt(cProto.SYNC_KEY);
                            
                            //当前帧号
                            buff.WriteInt(frameCount);
                            
                            //所有用户的合并数据
                            buff.WriteString(keyData);
                            
                            //发送给所有客户端
                            for (int i = 0; i < clientList.Count; ++i)
                            {
                                clientList[i].Send(buff);
                            }

                            // 进入下一帧
                            frameCount += 1;
                        }
                    }

                    break;
                case cProto.START:
                    break;
            }
        }
    }
}